package com._54programer.ws;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com._54programer.entity.Group;
import com._54programer.ws.handler.WsServerHandler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class NBind {

	// 保持连接的用户组 []
	private static Map<String, Set<String>> groups = WsServerHandler.groups;
	// 保持连接的用户
	private static Map<String, Channel> users = WsServerHandler.users;
	// 保持连接的用户
	private static Map<String, Channel> uids = WsServerHandler.uids;
	// 活跃的客户端连接
	private static ChannelGroup clients = WsServerHandler.clients;

	// ***********************************************************************/
	public static void bindGroup(ChannelHandlerContext ctx, String groupId) {
		if (groups.containsKey(groupId)) {
			groups.get(groupId).add(ctx.channel().id().asShortText());
		} else {
			Set<String> cid = new HashSet<String>();
			cid.add(ctx.channel().id().asShortText());
			groups.put(groupId, cid);
		}
	}

	/**
	 * 遍历解绑group中channelid
	 * 
	 * @param cid -> channelid
	 */
	public static void unbindGroup(String cid) {
		synchronized (groups) {
			//log.info("delete before => cid:{},groups:{}", cid, groups);
			for (String groupId : groups.keySet()) {
				groups.get(groupId).remove(cid);
			}
			//log.info("delete after => cid:{},groups:{}", cid, groups);
		}
	}

	public static void unbindGroup(ChannelHandlerContext ctx, String groupId) {
		if (groups.containsKey(groupId)) {
			groups.get(groupId).remove(ctx.channel().id().asShortText());
		}
	}

	public static void bindUser(ChannelHandlerContext ctx, String user) {
		if (!users.containsKey(user)) {
			users.put(user, ctx.channel());
		}
	}

	public static void unbindUser(ChannelHandlerContext ctx, String user) {
		if (users.containsKey(user)) {
			users.remove(user);
		}
	}

	public static void bindUid(ChannelHandlerContext ctx, String uid) {
		if (!uids.containsKey(uid)) {
			uids.put(uid, ctx.channel());
		}
	}

	public static void unbindUid(ChannelHandlerContext ctx, String uid) {
		if (uids.containsKey(uid)) {
			uids.remove(uid);
		}
	}

	public static void unbindUser(String token_username) {
		if (users.containsKey(token_username)) {
			//log.info("delete before : users : {}", users);
			//log.info("delete user:{}", token_username);
			users.remove(token_username);
			//log.info("delete after : users : {}", users);
		}
	}

	public static void unbindUid(String token_uid) {
		if (uids.containsKey(token_uid)) {
			//log.info("delete before : uids : {}", uids);
			//log.info("delete user:{}", token_uid);
			uids.remove(token_uid);
			//log.info("delete after : uids : {}", uids);
		}
	}

	////////////////////////////////////// send/////////////////////////////////////
	public static void sendByGroup(String groupId, String message) {
		if (groups.containsKey(groupId)) {
			for (Channel channel : clients) {
				for (String cid : groups.get(groupId)) {
					if (channel.id().asShortText().equals(cid))
						channel.writeAndFlush(new TextWebSocketFrame(message));
				}
			}
		}
	}

	public static void sendByUid(String uid, String message) {
		if (uids.containsKey(uid)) {
			uids.get(uid).writeAndFlush(new TextWebSocketFrame(message));
		}
	}

	public static void sendByUser(String user, String message) {
		if (users.containsKey(user)) {
			users.get(user).writeAndFlush(new TextWebSocketFrame(message));
		}
	}

	public static void sendAll(String message) {
		clients.writeAndFlush(new TextWebSocketFrame(message));
	}

	public static void send(ChannelHandlerContext ctx, String message) {
		ctx.writeAndFlush(new TextWebSocketFrame(message));
	}

	/***********************************************************/
	public static Set<Group> getAllGroupUsers() {

		Set<String> onlineUser = new HashSet<>();
		for (String username : users.keySet()) {
			String cid = users.get(username).id().asShortText();
			onlineUser.add(cid);
		}

		// 所有用户临时list
		List<Group> cidList = new ArrayList<Group>();
		// 提取所有gpid
		for (String gpid : groups.keySet()) {
			// 提取所有用户cid
			Set<String> cidSet = groups.get(gpid);
			for (String cidtmp : cidSet) {
				String id = cidtmp;
				if (onlineUser.contains(id)) {
					Group group = new Group();
					group.setCid(id);
					Set<String> groupSet = new HashSet<>();
					groupSet.add(gpid);
					group.setGpid(groupSet);
					cidList.add(group);
				} else {
					groups.get(gpid).remove(id);
				}
			}
		}
		log.info("所有组用户信息:{}", cidList);
		// 合并用户
		Set<Group> gps = new HashSet<>();
		for (Group group : cidList) {
			for (Group group2 : cidList) {
				if (group.getCid().equals(group2.getCid())) {
					group.getGpid().addAll(group2.getGpid());
				}
			}
			gps.add(group);
		}
		log.info("所有组用户信息:{}", gps);
		return gps;
	}

	public static Map<String, Set<String>> getUserGroupId_ByUid(String uid) {
		return groups;
	}

	public static Map<String, Set<String>> getUserGroupId_ByUame(String username) {
		return groups;
	}

}
